/*
* Author:  Greg Nowak and Vaibhav Sharma
* Michigan State University
* 
* This is the implementation of the NFC Wireless Sensor Network Application
*/
#include "Timer.h"  /* For timer control */
#include "printf.h"
module NFCWirelessC
{
  	uses interface Timer<TMilli> as Timer0;
  	uses interface Timer<TMilli> as Timer1;
 	uses interface Leds;
  	uses interface Boot;
	uses interface LogRead;
	uses interface LogWrite;
	uses interface Read<uint16_t>;

    uses interface Packet;
    uses interface AMPacket;
    uses interface AMSend;
    uses interface Receive;
    uses interface SplitControl as AMControl;
}
implementation
{
  /***  Module Variables Start ************************************/
 
  /* Data logging variables */
	typedef nx_struct flashLogEntry_t 
	{
    	nx_uint16_t timeStamp;
    	nx_uint16_t temperature;
    	nx_uint8_t nodeID;
    	nx_uint8_t sentStatus;
  	} flashLogEntry_t;

  	bool mLogBusy = FALSE;  	
    flashLogEntry_t mLocalEntry;
    uint16_t MAX_NUM_LOG_ENTRIES = 25;  /* Just for experimentation, not actual!*/
  
  /*  Temperature sensing variables */
  uint8_t mTemperatureReading = 0;
  bool mReadBusy = FALSE;
  /*******************************************************/
  /* This is the code that is called when the system starts.*/
  event void Boot.booted()
  {
    call Timer0.startPeriodic( 1000 );
    /* Clear the log on start up for DEBUG only */
    if (call LogWrite.erase() != SUCCESS) {
		printf("LogWrite.erase Failed\n");
    }
    call AMControl.start();     
  }
  /* 
   * This is called whenever timer 0 is fired
   */
  event void Timer0.fired()
  {
  	static int state=0;
  	static int timeStamp = 0;
  	static uint16_t packetCountWritten = 0;
  	static uint16_t packetCountRead = 0;
    call Leds.led1Toggle();
    call Leds.led0Toggle();
    
    timeStamp++;
    if( state == 0)
    {
    	//printf("Toggle LED State Off\r\n");
    	state=1;
    	//printfflush();
    	
    	/* Write to the log */
    	if( !mReadBusy && !mLogBusy && packetCountWritten < MAX_NUM_LOG_ENTRIES)
    	{
    		mLogBusy = TRUE;
    		mReadBusy = TRUE;
    		
    		/* Take a temperature reading */
    		if( call Read.read() != SUCCESS)
    		{
    			printf("Reading temperature failed\n");    		
			}
			
    			    	
	    	mLocalEntry.timeStamp = timeStamp;
	    	mLocalEntry.temperature = mTemperatureReading;   	
	    	mLocalEntry.nodeID = 10;
	    	mLocalEntry.sentStatus = 0;
	    	
	    	/* Write data to log */
	    	if (call LogWrite.append(&mLocalEntry, sizeof(flashLogEntry_t)) != SUCCESS) {
				mLogBusy = FALSE;
	      	}else{
	      		packetCountWritten++;  //Increase the number of packets written
  			   	printf("Write packet\r\n");
	      		printf("      Time Stamp: %u\r\n", mLocalEntry.timeStamp);
	      		printf("      Temperature: %u\r\n", mLocalEntry.temperature);
	      		printf("      Node ID: %u\r\n", mLocalEntry.nodeID);
	      		printf("      Sent Status: %u\r\n", mLocalEntry.sentStatus);
	      		printfflush();
	      	}
	      	
	      	mTemperatureReading = 0; /* Reset temperature reading */
	      	mLogBusy = FALSE;
	      	mReadBusy = FALSE;

      	}
    }else{
    	state=0;
    	//printf("Toggle LED State On\r\n");
    	//printfflush();
    	/* Read the entry */
    	/* Test:  read every other packet */
    	if( packetCountWritten >=  MAX_NUM_LOG_ENTRIES)
    	{
	    	if( !mLogBusy && packetCountRead < packetCountWritten)
	    	{
	    		packetCountRead++;
	    	    if (call LogRead.read(&mLocalEntry, sizeof(flashLogEntry_t)) != SUCCESS) {
					// Handle error.
	    		}
	    	}
    	}
    }
    
    
  }
  
  /***************************************************/
  /*  Flash Logger */
	
    event void LogRead.readDone(void* buf, storage_len_t len, error_t err) 
    {
    	if( !mLogBusy)
    	{
	    	//Check to see if the packet read is the right size
	        if ( (len == sizeof(flashLogEntry_t)) && (buf == &mLocalEntry) ) 
	        {
	      		printf("Read packet\r\n");
	      		printf("      Time Stamp: %u\r\n", mLocalEntry.timeStamp);
	      		printf("      Temperature: %u\r\n", mLocalEntry.temperature);
	      		printf("      Node ID: %u\r\n", mLocalEntry.nodeID);
	      		printf("      Sent Status: %u\r\n", mLocalEntry.sentStatus);
	      		printfflush();
	    	}else if( call LogWrite.erase() != SUCCESS)
	    	{
	    		//We tried to erase the log because we lost synchronization
	    		printf("Log erase failed\r\n");
	    		printfflush();
	    	}    	
    	}
	}
	
	event void LogWrite.eraseDone(error_t err) 
	{
	}
	event void LogWrite.appendDone(void* buf, storage_len_t len, 
                                 bool recordsLost, error_t err) 
    {
		mLogBusy = FALSE;	
	}

 	event void LogRead.seekDone(error_t err) 
 	{
 	}

  	event void LogWrite.syncDone(error_t err) 
  	{
  	}
	
  /**************************************************/
  
  /***** Sensor Reading Start ***********************/
  event void Read.readDone(error_t result, uint16_t data) {
  	if( !mReadBusy )
  	{   
	    if (result != SUCCESS)
		{
	  		/* Set the data to garbage because it wasn't right anyway */
	  		data = 0xffff;
		}
		
		mTemperatureReading = data;//(data + 126)/4096;	
	}	  	
  }		
 
 
 /****** Sensor Reading End ************************/

  bool radioBusy = FALSE;
  message_t pkt;
  
  event void AMControl.startDone(error_t err) {
    if (err == SUCCESS) {
      call Timer1.startPeriodic(2000);
    }
    else {
      call AMControl.start();
    }
  }

  event void AMControl.stopDone(error_t err) {
  }

  event void Timer1.fired() {
    if (!radioBusy) {
		flashLogEntry_t* btrpkt = (flashLogEntry_t*)(call Packet.getPayload(&pkt, sizeof (flashLogEntry_t)));
		btrpkt = &mLocalEntry;
		if (call AMSend.send(AM_BROADCAST_ADDR, &pkt, sizeof(flashLogEntry_t)) == SUCCESS) {
		  radioBusy = TRUE;
		}
	}
  }
  
  event void AMSend.sendDone(message_t* msg, error_t error) {
    if (&pkt == msg) {
      radioBusy = FALSE;
    }
  }

  event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) {
    if (len == sizeof(flashLogEntry_t)) {
	  flashLogEntry_t* btrpkt = (flashLogEntry_t*)payload;
      printf("Received a packet\n");
	}
	return msg;
  }




}
